package practica3;

import java.util.ArrayList;

import weka.classifiers.Evaluation;
import weka.classifiers.bayes.BayesNet;
import weka.classifiers.bayes.net.search.global.K2;
import weka.classifiers.rules.OneR;
import weka.core.Instances;

/**Clase principal*/
public class Main {
	
	public static void main(String[] args) throws Exception {
		
		// 1. CARGAR LOS DATOS
		LoadDataFile ldf = new LoadDataFile();
		if(args.length < 8){ //Tiene que haber 8 archivos.
			ldf.incorrectParams();
			return;
		}
		Instances train = null, test = null;
		try{
			train = ldf.loadInstances(args[0]);
			test = ldf.loadInstances(args[1]);
		}catch(Exception e){
			System.out.println("ERROR AL CARGAR LOS DATOS");
			return;
		}
		
		//2. PREPROCESAR
		Preprocess p = new Preprocess();
		
			//2.1 Baseline
			Instances trainOneR = p.normalize(train);
			Instances testOneR = p.normalize(test);
		
			//2.2 Bayes Network
			Instances trainBN = p.discretize(train);
			Instances testBN = p.discretize(test);
			
		//3. CLASIFICAR
			
			//3.1 Baseline (Calidad esperada)
			ScanParamsOneR spo = new ScanParamsOneR();
			int b = -1;
			try{
				b = spo.classify(trainOneR);
			}catch(Exception e){
				System.out.println("ERROR: Comprueba que los datos de train sean correctos (ej. que no falte la clase)");
				return;
			}
			OneR estimatorOneR = new OneR();
				
			estimatorOneR.setMinBucketSize(b); //Establecer el estimador con la mejor B obtenida.
			estimatorOneR.buildClassifier(trainOneR);
			Predictions.obtenerArchivoCalidad(args[4], spo.getEvaluador(), "ONER", "ESPERADA");
			
			//3.2 Baseline (Calidad maxima)
			UpperBoundsOneR ub = new UpperBoundsOneR();
			ub.classify(trainOneR);
			Predictions.obtenerArchivoCalidad(args[5], ub.getEvaluador(), "ONER", "MAXIMA (NO-HONESTO)");

				
			//3.3 Bayes Network (Calidad esperada)
			ScanParamsAlgorithm spa = new ScanParamsAlgorithm();
			ArrayList<Integer> bestBN = spa.classify(trainBN);
			BayesNet estimatorBN = new BayesNet();
			K2 sa = new K2();
				
			estimatorBN.setSearchAlgorithm(sa);
			sa.setMaxNrOfParents(bestBN.get(0)); //Inicializamos el numero de padres 
				
			if (bestBN.get(1) == 0) 
				sa.setInitAsNaiveBayes(false); //Red inicial vacia
			else 
				sa.setInitAsNaiveBayes(true); //Red inicial NaveBayes
			
			estimatorBN.buildClassifier(trainBN);
			Predictions.obtenerArchivoCalidad(args[6], spa.getEvaluador(), "BAYES NETWORK", "ESPERADA");
			
			//3.4 Bayes Network (Calidad maxima)
			UpperBoundsAlgorithm uba = new UpperBoundsAlgorithm();
			uba.classify(trainBN);
			Predictions.obtenerArchivoCalidad(args[7], uba.getEvaluador(), "BAYES NETWORK", "MAXIMA (NO-HONESTO)");
			
		//4. PREDICCIONES 
		Predictions pred = new Predictions();
		
			//4.1 Baseline
			Evaluation evaluatorOneR = new Evaluation(trainOneR);
			try{
				pred.predictClass(testOneR, estimatorOneR, evaluatorOneR, args[2]);
			}catch(Exception e){
				System.out.println("ERROR PREDICCIONES: Comprueba que los datos de test sean correctos (ej. que no falte la clase)");
				return;
			}
		
			//4.2 Bayes Network
			Evaluation evaluatorBN = new Evaluation(trainBN);
			pred.predictClass(testBN, estimatorBN, evaluatorBN, args[3]);

		
		//5. LIBRERIAS 
		CVParam cv = new CVParam();
		GridSearch gs = new GridSearch();
			
			//5.1 Baseline
			cv.paramSelection(trainOneR);
			gs.gSearch(trainOneR);
			
			//5.2 Bayes Network
			cv.paramSelection(trainBN);
			gs.gSearch(trainBN);
    }
	
}
